package com.cskaoyan.javase.array._5call;

import java.util.Arrays;

/**
 * 什么是方法的传值问题?
 * 我们在调用方法时,需要给方法传入实参,在方法的执行过程中,再方法内部,这个参数的取值可能会被修改
 *      那么在方法执行完毕,方法出栈后,原先的实参的值会随之改变吗?
 *      这就是方法的传值问题,必须要搞懂它,不然方法的调用就会有问题
 *
 * 方法的传值的两种常见方式:
 *      1.值传递(call by value)指的是方法得到的参数是一个实参的拷贝,实参的副本
 *          那么方法结束后,对原本的实参的取值是不能做任何修改的
 *      2.引用传递(call by reference)指的是方法得到参数的是实参的地址(就是实参本身)
 *          那么方法结束后,对原本的实参的取值就会产生影响.
 *
 * 接下来开始验证:
 *      1.我们通过一个方法,将一个int参数变为它的二倍,发现实参的取值没有随着方法的调用改变
 *          所以至少对于基本数据类型而言,Java是值传递的
 *      2.我们通过一个方法,将一个数组中的元素变为原先的二倍,发现随着方法的调用,调用结束后数组中的元素发生了变化
 *          所以对于引用数据类型,Java是引用传递的
 *      总结:
 *          Java对于基本数据类型是值传递,对于引用数据类型是引用传递的
 *
 *     以上结论是大错特错的,是典型的网络上复制粘贴博主的经典错误言论,实际上Java是没有引用传递的,Java只有值传递.
 *
 *     Java当中的局部变量仅在方法的作用域内部生效,不能在外部生效,Java没有引用传递的语法基础。
 *
 * @since 16:04
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*int a = 10;
        doubleParameter(a);
        System.out.println(a);*/

        /*int[] arr = {1, 2, 3};
        System.out.println("方法调用之前:" + Arrays.toString(arr));
        doubleArr(arr);
        System.out.println("方法调用之后:" + Arrays.toString(arr));*/

        int[] arr1 = {666, 777, 888};
        int[] arr2 = {6, 7, 8};
        /*
            思考:
                能否交换成功呢?
                成功代表什么?
                    如果能够成功,说明方法得到的是引用的本身(地址),不是拷贝,说明java是引用传递
                失败代表什么?
                    如果失败,说明得到的是拷贝,是值传递
         */
        System.out.println("交换之前arr1:" + Arrays.toString(arr1));
        System.out.println("交换之前arr2:" + Arrays.toString(arr2));
        swap(arr1, arr2);
        System.out.println("交换之后arr1:" + Arrays.toString(arr1));
        System.out.println("交换之后arr2:" + Arrays.toString(arr2));


    }

    public static void doubleParameter(int a) {
        a = 100;
    }

    public static void doubleArr(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] *= 2;
        }
    }

    // 需求: 直接交换两个int数组的引用
    public static void swap(int[] arr1, int[] arr2) {
        // 交换需要临时工
        int[] temp = arr1;
        arr1 = arr2;
        arr2 = temp;
        // 在方法的内部是交换成功的,但是这个成功不会体现在外面
        System.out.println("交换之中arr1:" + Arrays.toString(arr1));
        System.out.println("交换之中arr2:" + Arrays.toString(arr2));
    }
}
